﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKRevitBase.TopologySuite;
using YJKRevitDimension.LevelDimension;
using YJKRevitKernel.ElementSearchUtility.LinkDocumentSuite;
using YJKRevitKernel.RevitTopologySuite;
using YJKGeometryFuncs;
using YJKPatternSign.StairsRoomSection.DataDefine;
using YJKPatternSign.StairsRoomSection.Kit;
using YJKLoopSearch;

namespace YJKPatternSign.StairsRoomSection.SignElems
{
	internal class FloorSign
	{
		public FloorSign(ExternalCommandData commandData, List<BaseLinkDocumentResultBean> lstFloor, SectionViewData ViewData, Dictionary<string, double> DicLayerInfo)
		{
			this.m_commandData = commandData;
			this.m_lstFloor = lstFloor;
			this.m_ViewData = ViewData.clone();
			this.m_DicLayerInfo = DicLayerInfo;
			this.m_doc = this.m_ViewData.SectionView.Document;
		}

		public bool Sign()
		{
			LevelDimensionManager dimManager = new LevelDimensionManager(this.m_commandData);
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in this.m_lstFloor)
			{
				double num = this.GetFloorElevator(baseLinkDocumentResultBean);
				num = Math.Round(num, 6);
				if (!Geometry.IsEqual(num, 0.0))
				{
					List<Curve> lstAllCrv = new List<Curve>();
					CommonFun.FindCurveInNormal(ref lstAllCrv, XYZ.BasisZ, baseLinkDocumentResultBean.UseElement);
					List<XYZ> list = new List<XYZ>();
					if (this.GetFloorCntPoint(lstAllCrv, baseLinkDocumentResultBean.GetTotalTransform(), list))
					{
						foreach (XYZ xyz in list)
						{
							XYZ landPos = new XYZ(xyz.X, xyz.Y, num);
							SignCommon.CreateElevatorDim(dimManager, this.m_doc, landPos, num, this.m_DicLayerInfo);
						}
					}
				}
			}
			return true;
		}

		private double GetFloorElevator(BaseLinkDocumentResultBean bean)
		{
			Element element = bean.UseElement as Floor;
			Transform totalTransform = bean.GetTotalTransform();
			double dVal = element.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_TOP).AsDouble();
			return SignCommon.TransformDouble(totalTransform, dVal);
		}

		private bool GetFloorCntPoint(List<Curve> lstAllCrv, Transform FloorTransform, List<XYZ> lstCntPt)
		{
			List<List<Curve>> lstlstOutSideCrv = new List<List<Curve>>();
			List<List<Curve>> list = new List<List<Curve>>();
			try
			{
				this.GetFloorOutSide(lstAllCrv, FloorTransform, ref lstlstOutSideCrv);
				this.GetFloorOutSideBySecline(lstlstOutSideCrv, list);
			}
			catch (Exception)
			{
				return false;
			}
			foreach (List<Curve> list2 in list)
			{
				CurveArray curveArray = new CurveArray();
				foreach (Curve curve in list2)
				{
					curveArray.Append(curve);
				}
				XYZ item = YJKRevitTools.Centroid(curveArray);
				lstCntPt.Add(item);
			}
			return true;
		}

		private bool GetFloorOutSideBySecline(List<List<Curve>> lstlstOutSideCrv, List<List<Curve>> lstlstJoinCrv)
		{
			if (lstlstOutSideCrv.Count < 1)
			{
				return true;
			}
			try
			{
				List<Curve> list = new List<Curve>();
				Curve curve = this.m_ViewData.SecLine;
				double num = lstlstOutSideCrv[0][0].GetEndPoint(0).Z - curve.GetEndPoint(0).Z;
				Transform transform = Transform.CreateTranslation(XYZ.BasisZ * num);
				curve = curve.CreateTransformed(transform);
				list.Add(curve);
				XYZ endPoint = curve.GetEndPoint(0);
				XYZ endPoint2 = curve.GetEndPoint(1);
				XYZ xyz = this.m_ViewData.m_viewDir.Negate();
				Line item = Line.CreateBound(endPoint2, endPoint2 - 2.0 * xyz);
				list.Add(item);
				list.Add(Line.CreateBound(endPoint2 - 2.0 * xyz, endPoint - 2.0 * xyz));
				Line item2 = Line.CreateBound(endPoint - 2.0 * xyz, endPoint);
				list.Add(item2);
				CurveLoop curveLoop = this.GetCurveLoop(list);
				List<RevitPolygonDataBean> list2 = new List<RevitPolygonDataBean>();
				foreach (List<Curve> input in lstlstOutSideCrv)
				{
					list2.Add(new RevitPolygonDataBean(this.GetCurveLoop(input), null, 3));
				}
				RevitPolygonDataBean inputOne = new RevitPolygonDataBean(curveLoop, null, 3);
				RevitPolygonRelateOperater revitPolygonRelateOperater = new RevitPolygonRelateOperater();
				RevitPolygonBooleanOperater revitPolygonBooleanOperater = new RevitPolygonBooleanOperater();
				foreach (RevitPolygonDataBean inputTwo in list2)
				{
					TopologyRelateKindEnum topologyRelateKindEnum;
					List<RevitPolygonDataBean> list3;
					if (revitPolygonRelateOperater.TryGetPolygonRelate(inputOne, inputTwo, out topologyRelateKindEnum) && topologyRelateKindEnum != TopologyRelateKindEnum.Disjoint && revitPolygonBooleanOperater.TryGetBooleanResult(inputOne, inputTwo, BooleanOperatorKindEnum.Intersection, out list3))
					{
						foreach (RevitPolygonDataBean revitPolygonDataBean in list3)
						{
							lstlstJoinCrv.Add(revitPolygonDataBean.ShellCurveLoop.ToList<Curve>());
						}
					}
				}
			}
			catch (Exception)
			{
				throw;
			}
			return true;
		}

		private CurveLoop GetCurveLoop(List<Curve> input)
		{
			CurveLoop curveLoop = new CurveLoop();
			foreach (Curve curve in input)
			{
				curveLoop.Append(curve);
			}
			return curveLoop;
		}

		private bool GetFloorOutSide(List<Curve> lstAllCrv, Transform FloorTransform, ref List<List<Curve>> curvesArea)
		{
			List<Curve> list = new List<Curve>();
			StructureLoopSearcher structureLoopSearcher = new StructureLoopSearcher(this.m_doc, 0.001);
			List<Pole2D> list2 = new List<Pole2D>();
			foreach (Curve curve in lstAllCrv)
			{
				Curve curve2 = curve.CreateTransformed(FloorTransform);
				list.Add(curve2);
				Pole2D item = Pole2D.TransformWallToStructure2DPole(curve2, null, 0.0, 0.0);
				list2.Add(item);
			}
			new List<Curve>();
			curvesArea = structureLoopSearcher.GetFullFloorEdgeLoops(list2, StructureLoopSearcher.SearchEdgeLocation.SEL_Outside);
			List<List<Curve>> list3 = new List<List<Curve>>();
			foreach (List<Curve> list4 in curvesArea)
			{
				List<Pole2D> list5 = new List<Pole2D>();
				foreach (Curve curve3 in list4)
				{
					Pole2D item2 = Pole2D.TransformWallToStructure2DPole(curve3, null, 0.0, 0.0);
					list5.Add(item2);
				}
				List<List<Curve>> cellsEdgeLoops = structureLoopSearcher.GetCellsEdgeLoops(list5, true);
				for (int i = 0; i < cellsEdgeLoops.Count; i++)
				{
					list3.Add(cellsEdgeLoops[i]);
				}
			}
			curvesArea = list3;
			return true;
		}

		private Document m_doc;

		private ExternalCommandData m_commandData;

		private List<BaseLinkDocumentResultBean> m_lstFloor;

		private SectionViewData m_ViewData;

		private Dictionary<string, double> m_DicLayerInfo;
	}
}
